package org.rc.client;

import cn.hutool.dfa.WordTree;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.rc.cache.FrontTextSessionCache;
import org.rc.config.CommonConstants;
import org.rc.dto.*;
import org.rc.util.BusinessTool;
import org.springframework.util.CollectionUtils;

import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class AudioTextClient extends WebSocketClient {

    private final String micMac;

    private List<KeyWordGroup> keyWordGroups;

    private List<String> names;

    public AudioTextClient(URI serverUri, String micMac,List<KeyWordGroup> keyWordGroups, List<String> names) {
        super(serverUri);
        this.micMac = micMac;
        this.keyWordGroups = keyWordGroups;
        this.names = names;
        try{
            if(connectBlocking()){
                log.info("与转写服务建立连接成功");
            }else{
                log.error("与转写服务建立连接失败");
                closeBlocking();
            }
        }catch (Exception e){
            log.error("与转写服务建立连接失败,e--->",e);
        }
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {

    }

    @Override
    public void onMessage(String message) {
        if(StringUtils.isNotEmpty(message)){
            JSONObject jsonObject = JSONObject.parseObject(message);
            if(jsonObject.get("type").equals("text") && jsonObject.get("audioDevId").equals(micMac)){
                MicTextDto micTextDto = JSONObject.parseObject(message,MicTextDto.class);
                String text = micTextDto.getText();
                if(StringUtils.isNotEmpty(text)){
                    checkElementAlarmAndSend(text);
                }
            }
        }
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        log.info("与设备{}，断开连接",micMac);
    }

    @Override
    public void onError(Exception e) {
        log.error("与设备["+micMac+"]连接发生错误",e);
    }

    private void checkElementAlarmAndSend(String text){
        List<String> alarmTypes = new ArrayList<>();
        try{
            text = checkName(text);
            text = checkAlarm(text,alarmTypes);
        }catch (Exception e){
            log.error("处理关键词预警出现异常，e--->",e);
        }finally {
            FrontTextDto frontTextDto = new FrontTextDto("text",text,new SimpleDateFormat("HH:mm:ss").format(new Date()));
            FrontTextSessionCache.sendText(micMac,JSONObject.toJSONString(frontTextDto));
            if(!CollectionUtils.isEmpty(alarmTypes)){
                FrontAlarmDto frontAlarmDto = new FrontAlarmDto("alarm",String.join(",",alarmTypes));
                FrontTextSessionCache.sendText(micMac,JSONObject.toJSONString(frontAlarmDto));
            }
        }
    }

    private String checkName(String text){
        WordTree tree = new WordTree();
        if(CollectionUtils.isEmpty(names)){
            return text;
        }
        tree.addWords(names);
        List<String> matches = BusinessTool.removeDuplicateAndContained(tree.matchAll(text,-1,true,true));
        if(!CollectionUtils.isEmpty(matches)){
            for(String match : matches){
                text = text.replaceAll(match, String.format(CommonConstants.ELEMENT_STYLE_WEB,match));
            }
        }
        return text;
    }

    private String checkAlarm(String text,List<String> alarmTypes){
        if(!CollectionUtils.isEmpty(keyWordGroups)){
            for(KeyWordGroup keyWordGroup : keyWordGroups){
                WordTree tree = new WordTree();
                String alarmType = keyWordGroup.getFatherDic().getDictName();
                List<String> keyWords = keyWordGroup.getChildDics().stream().map(KeyWordDictitem :: getDictName).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(keyWords)){
                    continue;
                }
                tree.addWords(keyWords);
                List<String> matches = tree.matchAll(text);
                if(!CollectionUtils.isEmpty(matches)){
                    alarmTypes.add(alarmType);
                }
                for(String match : matches){
                    text = text.replaceAll(match, String.format(CommonConstants.ALARM_STYLE,match));
                }
            }
        }
        return text;
    }
}
